#include "script_engine.h"
#include "service_mgr.h"
#include "message_service.h"
#include "time_mgr.h"
#include "message.h"
#include "c_msg.h"
#include "script_msg.h"

ScriptEngine::ScriptEngine() {

}

ScriptEngine::~ScriptEngine() {

}

int32 _createGuid64(lua_State* L) {
	int32 appid = (int32)lua_tonumber(L, 1);
	int32 type = (int32)lua_tonumber(L, 2);
	int32 serial = (int32)lua_tonumber(L, 3);
	lua_pushinteger(L, Guid64(APPID, type, serial));
	return 1;
}

int32 _newService(lua_State* L) {
	uint64 retHandle = lua_tointeger(L, 1);
	uint64 coid = lua_tointeger(L, 2);
	uint64 newHandle = lua_tointeger(L, 3);
	const char* clsName = lua_tostring(L, 4);
	uint64 processInterval = lua_tointeger(L, 5);
	CMessage msg("reqNewLuaService");
	msg << retHandle << coid << newHandle << clsName << processInterval;
	gMessageMgr.sendMessage(gServiceMgr.getHandle(), msg.dataStream());
	return 0;
}

int32 _remoteCall(lua_State* L) {
	int32 topIndex = lua_gettop(L);
	uint64 retHandle = lua_tointeger(L, 1);
	uint64 coid = lua_tointeger(L, 2);
	uint64 targetHandle = lua_tointeger(L, 3);
	const char* fName = lua_tostring(L, 4);

	uint8 msgType = MSG_TC;
	CMessage msg("reqRemoteScriptCall");
	msg << retHandle << coid << targetHandle << fName;
	if (topIndex > 4) {
		ScriptRets params;
		params << (uint8)(topIndex - 4);
		for (int32 i = 5; i <= topIndex; i++) {
			LuaVm::readRetEx(L, i, params);
		}
		DataStream* ds = params.createStreamReader().dataStream();
		shengine_assert(ds);
		msg.appenBuffer(ds->stream_.data(), (int32)ds->stream_.size());
	}
	
	gMessageMgr.sendMessage(targetHandle, msg.msg());
	return 0;
}

int32 _sleep(lua_State* L) {
	uint64 ms = lua_tointeger(L, 1);
	Sleep((uint32)ms);
	return 0;
}

int32 _getTime(lua_State* L) {
	lua_pushinteger(L, gTimeMgr.getTime());
	return 1;
}

int32 _getTimeMs(lua_State* L) {
	lua_pushinteger(L, gTimeMgr.getTimeMs());
	return 1;
}

int32 _kick(lua_State* L) {
	uint64 kickHandle = lua_tointeger(L, 1);
	CMessage msg("reqKickService");
	gMessageMgr.sendMessage(kickHandle, msg.msg());
	return 0;
}

int32 _finalsaveok(lua_State* L) {
	uint64 handle = lua_tointeger(L, 1);
	CMessage msg("retFinalSaveOk");
	gMessageMgr.sendMessage(handle, msg.msg());
	return 0;
}

int32 _exit(lua_State* L) {
	CMessage msg("reqExitProcess");
	gMessageMgr.sendMessage(gServiceMgr.getHandle(), msg.msg());
	return 0;
}

int32 _testlock(lua_State* L) {
	static AtomRef nolocktimes = 0;
	static AtomRef locktimes = 0;
	bool islock = lua_toboolean(L, 1) == 1;
	if (islock) {
		ATOM_ADD(&locktimes, 1);
	}
	else {
		ATOM_ADD(&nolocktimes, 1);
	}
	return 0;
}

void ScriptEngine::loadGameLibs() {
	lua_pushinteger(L, APPID);
	lua_setglobal(L, "APPID");
		
	lua_newtable(L);
	lua_pushliteral(L, "create_guid");
	lua_pushcfunction(L, _createGuid64);
	lua_settable(L, -3);

	lua_pushliteral(L, "new_service");
	lua_pushcfunction(L, _newService);
	lua_settable(L, -3);

	lua_pushliteral(L, "remote_call");
	lua_pushcfunction(L, _remoteCall);
	lua_settable(L, -3);

	lua_pushliteral(L, "time");
	lua_pushcfunction(L, _getTime);
	lua_settable(L, -3);

	lua_pushliteral(L, "tick");
	lua_pushcfunction(L, _getTimeMs);
	lua_settable(L, -3);

	lua_pushliteral(L, "sleep");
	lua_pushcfunction(L, _sleep);
	lua_settable(L, -3);

	lua_pushliteral(L, "kick");
	lua_pushcfunction(L, _kick);
	lua_settable(L, -3);

	lua_pushliteral(L, "exit");
	lua_pushcfunction(L, _exit);
	lua_settable(L, -3);

	lua_pushliteral(L, "finalsaveok");
	lua_pushcfunction(L, _finalsaveok);
	lua_settable(L, -3);

	lua_pushliteral(L, "testlock");
	lua_pushcfunction(L, _testlock);
	lua_settable(L, -3);
	
	lua_setglobal(L, "_shengine");

}

